<!--
 * @Author: zulezhe
 * @Date: 2021-02-05 10:05:59
 * @LastEditors: zulezhe
 * @LastEditTime: 2021-02-20 17:53:50
 * @Description: In User Settings Edit
 * @FilePath: \canvas\02-进阶\鼠标点击泡泡动画.html
--><!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      html,
      body {
        width: 100%;
        height: 100%;
        background-color: #000;
      }
      * {
        margin: 0;
        padding: 0;
      }
      canvas {
        outline: 1px solid red;
      }
    </style>
  </head>
  <body>
    <script>
      /***
       * 需求: 鼠标点击某一个区域,出现随机数量,随机颜色,随机大小的泡泡,并且泡泡的大小会逐渐变小,而且泡泡的的位置是向外扩散的效果
       *
       * 分析:
       *    首先点击的时候出现随机数量,随机颜色,随机大小的泡泡很容易实现,关键是泡泡的扩散效果稍微要麻烦一点。
       * 我们知道在canvas中已经生成的canvas图像是无法更改状态的,所以需要实现动画效果的话一般是清除原有的图像然后生成不同位置不同
       * 状态的新图像,所以这里的扩散效果也就是需要不断清除原有的状态,绘制新的图像就行了
       *
       *  然后:就是计算扩散的坐标点,扩散的时候每个
       */
      class Ball {
        constructor(x, y, radius, color) {
          this.x = x;
          this.y = y;
          this.color = color;
          this.radius = radius;
          this.width = width;
          this.height = height;
          this.ctx = ctx;
          this.scaleX = 1;
          this.scaleY = 1;
          this.vx = 0;
          this.vy = 0;
        }
        draw() {
          this.ctx.save();
          this.ctx.beginPath();
          // 球球的移动
          this.ctx.translate(this.x, this.y);
          // 球球的缩小
          this.ctx.scale(this.scaleX, this.scaleY);
          this.ctx.fillStyle = this.color;
          this.ctx.arc(0, 0, this.radius, 0, 360 * (Math.PI / 180));
          this.ctx.fill();
          this.ctx.closePath();
          this.ctx.restore();
        }
      }
      /**
       * 随机数量
       */
      function randomCount(count = 10) {
        return Math.ceil(Math.random() * count);
      }
      /**
       * 随机颜色
       */
      function randomColor() {
        var r = Math.floor(Math.random() * 256); //随机生成256以内r值
        var g = Math.floor(Math.random() * 256); //随机生成256以内g值
        var b = Math.floor(Math.random() * 256); //随机生成256以内b值
        var alpha = Math.random(); //随机生成1以内a值
        return `rgb(${r},${g},${b},${alpha})`; //返回rgba(r,g,b,a)格式颜色
      }

      // 使用
      const container = document.body;
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      let width = container.offsetWidth;
      let height = container.offsetHeight;
      canvas.width = width;
      canvas.height = height;
      container.appendChild(canvas);
      const count = 20;
      let easing = 0.05;
      let opacticy = 0.6;
      let innerRadius = 30;
      let outterRadius = 150;
      let moreOutterRadius = 200;
      canvas.addEventListener("mousedown", (event) => {
        const ballList = [];
        for (let i = 0; i < count; i++) {
          // 这一步是随机生成圆的偏移坐标,生成的随机数可能是正的也可能是负的,两个随机数相减的结果就有正有负,所以
          // 点击以后就会根据鼠标点击的点在它的周围生成大小不一,位置遍布的规定个数和随机颜色的圆
          let offsetx = randomCount(50) - randomCount(50);
          let offsety = randomCount(50) - randomCount(50);
          let radius = randomCount(50);
          let color = randomColor();
          const ball = new Ball(event.x + offsetx, event.y + offsety, radius, color);
          //=========
          ball.x = event.x + Math.random() * innerRadius - Math.random() * innerRadius;
          ball.y = event.y + Math.random() * innerRadius - Math.random() * innerRadius;
          var x = event.x - ball.x;
          var y = event.y - ball.y;
          var scale = Math.abs(x / y);
          ball.dx = (((x < 0 ? 1 : -1) * moreOutterRadius) / Math.sqrt(scale * scale + 1)) * Math.random() * scale + event.x;
          ball.dy = (((y < 0 ? 1 : -1) * moreOutterRadius) / Math.sqrt(scale * scale + 1)) * Math.random() + event.y;
          //=========
          ballList.push(ball);
          ball.draw();
        }
        (function animate() {
          ctx.clearRect(0, 0, width, height);
          requestAnimationFrame(animate);
          ballList.map((item) => {
            //判断圆球的扩散方向
            //============
            item.vx = (item.dx - item.x) * easing;
            item.vy = (item.dy - item.y) * easing;
            item.x += item.vx;
            item.y += item.vy;
            console.log(item.x, item.y);
            //============
            item.scaleX += -item.scaleX * easing;
            item.scaleY += -item.scaleY * easing;
            item.draw();
          });
        })();
      });
    </script>
  </body>
</html>
